/*
 * Wazuh Vulnerability Scanner - Unit Tests
 * Copyright (C) 2015, Wazuh Inc.
 * March 5, 2024.
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public
 * License (version 2) as published by the FSF - Free Software
 * Foundation.
 */

#include "alertClearBuilder_test.hpp"
#include "../../../../shared_modules/utils/flatbuffers/include/syscollector_deltas_generated.h"
#include "../../../../shared_modules/utils/flatbuffers/include/syscollector_deltas_schema.h"
#include "../../../../shared_modules/utils/flatbuffers/include/syscollector_synchronization_generated.h"
#include "../../../../shared_modules/utils/flatbuffers/include/syscollector_synchronization_schema.h"
#include "../scanOrchestrator/alertClearBuilder.hpp"
#include "MockDatabaseFeedManager.hpp"
#include "MockOsDataCache.hpp"
#include "TrampolineOsDataCache.hpp"
#include "flatbuffers/flatbuffer_builder.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "json.hpp"
#include <unistd.h>

using ::testing::_;
using ::testing::HasSubstr;
using ::testing::ThrowsMessage;

namespace NSAlertClearBuilderTest
{
    constexpr auto TEST_DESCRIPTION_DATABASE_PATH {"queue/vd/descriptions"};

    const std::string SYNCHRONIZATION_INTEGRITY_CLEAR_MSG =
        R"(
            {
                "agent_info": {
                    "agent_id": "001",
                    "agent_ip": "192.168.33.20",
                    "agent_name": "focal",
                    "node_name": "node01"
                },
                "data_type": "integrity_clear",
                "data": {
                    "id": 1700236640,
                    "attributes_type": "syscollector_packages"
                }
            }
        )";

    const std::string CVEID {"CVE-2024-1234"};
} // namespace NSAlertClearBuilderTest

using namespace NSAlertClearBuilderTest;

void AlertClearBuilderTest::SetUp()
{
    std::filesystem::create_directories("queue/vd");

    // Policy manager initialization.
    const auto& configJson {nlohmann::json::parse(R"({
    "vulnerability-detection": {
        "enabled": "yes",
        "index-status": "yes",
        "cti-url": "cti-url.com"
    },
    "osdataLRUSize":1000
    })")};
    PolicyManager::instance().initialize(configJson);
}

void AlertClearBuilderTest::TearDown()
{
    spOsDataCacheMock.reset();
    PolicyManager::instance().teardown();
    std::filesystem::remove_all("queue/vd");
}

TEST_F(AlertClearBuilderTest, TestSuccessfulIntegrityClear)
{
    Os osData {.hostName = "osdata_hostname",
               .architecture = "osdata_architecture",
               .name = "osdata_name",
               .codeName = "osdata_codeName",
               .majorVersion = "osdata_majorVersion",
               .minorVersion = "osdata_minorVersion",
               .patch = "osdata_patch",
               .build = "osdata_build",
               .platform = "osdata_platform",
               .version = "osdata_version",
               .release = "osdata_release",
               .displayVersion = "osdata_displayVersion",
               .sysName = "osdata_sysName",
               .kernelVersion = "osdata_kernelVersion",
               .kernelRelease = "osdata_kernelRelease"};

    spOsDataCacheMock = std::make_shared<MockOsDataCache>();
    EXPECT_CALL(*spOsDataCacheMock, getOsData(_)).WillRepeatedly(testing::Return(osData));

    auto spDatabaseFeedManagerMock = std::make_shared<MockDatabaseFeedManager>();

    flatbuffers::Parser parser;
    ASSERT_TRUE(parser.Parse(syscollector_synchronization_SCHEMA));
    ASSERT_TRUE(parser.Parse(SYNCHRONIZATION_INTEGRITY_CLEAR_MSG.c_str()));
    uint8_t* buffer = parser.builder_.GetBufferPointer();
    std::variant<const SyscollectorDeltas::Delta*, const SyscollectorSynchronization::SyncMsg*, const nlohmann::json*>
        syscollectorSynchronization = SyscollectorSynchronization::GetSyncMsg(reinterpret_cast<const char*>(buffer));
    auto scanContextOriginal = std::make_shared<TScanContext<TrampolineOsDataCache>>(syscollectorSynchronization);
    scanContextOriginal->m_isInventoryEmpty = false;

    TAlertClearBuilder<MockDatabaseFeedManager, TScanContext<TrampolineOsDataCache>> alertClearBuilder(
        spDatabaseFeedManagerMock);

    std::shared_ptr<TScanContext<TrampolineOsDataCache>> scanContextResult;
    EXPECT_NO_THROW(scanContextResult = alertClearBuilder.handleRequest(scanContextOriginal));

    EXPECT_EQ(scanContextResult->m_elements.size(), 0);
    EXPECT_EQ(scanContextResult->m_alerts.size(), 1);
    EXPECT_NE(scanContextResult->m_alerts.find("clear"), scanContextResult->m_alerts.end());

    auto& alert = scanContextResult->m_alerts["clear"];

    EXPECT_STREQ(alert.at("vulnerability").at("status").get_ref<const std::string&>().c_str(), "Clear");
    EXPECT_STREQ(alert.at("vulnerability").at("title").get_ref<const std::string&>().c_str(),
                 "There is no information of installed packages. Vulnerabilities cleared.");
    EXPECT_STREQ(alert.at("vulnerability").at("type").get_ref<const std::string&>().c_str(), "Packages");
}
